"""
目标:需要在天合项目中把需要跑脚本的任务获取到,然后同步到伯雷云正式版当中,并且需要在伯镭云的oss中添加一份相同的图片
"""
# TODO:需要去修改对应的数据信息
import json
import os
import time
import oss2
import requests
from config import OSS_TRINA_ID, OSS_TRINA_SECRET, OSS_TRINA_POINT, OSS_TRINA_BUCKET, OSS_CLOUD_ID, oss_CLOUD_SECRET, \
    OSS_CLOUD_POINT, OSS_CLOUD_BUCKET, get_task_trina_url, base_dir, phone_num, password, login_cloud_url, \
    create_task_url, project_id, OSS_PATH, update_status_url
from log import logger

while True:
    try:
        trina_auth = oss2.Auth(OSS_TRINA_ID, OSS_TRINA_SECRET)
        trina_bucket = oss2.Bucket(trina_auth, OSS_TRINA_POINT, OSS_TRINA_BUCKET)
        cloud_auth = oss2.Auth(OSS_CLOUD_ID, oss_CLOUD_SECRET)
        cloud_bucket = oss2.Bucket(cloud_auth, OSS_CLOUD_POINT, OSS_CLOUD_BUCKET)
    except Exception as e:
        logger.error(e)
    else:
        print('oss连接成功')
        break


class Server(object):
    def __init__(self, trina_bucket=None, cloud_bucket=None):
        self.trina_bucket = trina_bucket
        self.cloud_bucket = cloud_bucket
        self.get_task_trina_url = get_task_trina_url
        self.t_id = 0
        self.p_id = 0
        self.token = None
        self.address = None
        self.roof_type = None
        self.user_id = 0
        self.company_id = 0
        self.application_id = 0
        self.name = ""
        self.task_id = 0
        self.is_auto_upload = "yes"
        self.survey_type = "sroof"
        self.login_cloud(phone_num, password, login_cloud_url)

    def trina_get_task(self):
        content = requests.get(self.get_task_trina_url).json()
        if len(content) < 1:
            return 0, 0, ""
        content = content[0]
        p_id = content.get("trina_num", "")
        t_id = content.get("id", 0)
        raw_data = content.get("raw_data", "")
        self.address = content.get("address")
        self.roof_type = content.get("roof_type")
        self.name = content.get("name")
        self.is_auto_upload = content.get("is_auto_upload")
        self.survey_type = content.get("survey_type")
        self.p_id = p_id
        return t_id, p_id, raw_data

    def cloud_create_task(self):
        task_config = f"{self.survey_type}_{self.roof_type}_{self.t_id}_{self.p_id}"
        print(task_config)
        json_data = {
            "owner_id": self.user_id, "project_id": project_id, "name": self.name, "address": self.address,
            "task_config": task_config, "task_application_current": self.application_id, "task_status": 2
        }
        auth_token = {'Authorization': f"Token {self.token}"}
        content = requests.post(create_task_url, json=json_data, headers=auth_token).json()
        try:
            self.task_id = content['id']
        except Exception as e:
            print(e)
            return False
        else:
            return True

    def download_image(self, p_id, t_id, raw_data, local_path):
        """
        /bucket/勘探号/架次号/rawData/具体照片
        :return:
        """
        if self.is_auto_upload != "NO":
            image_list = self.parse_content_raw_data(raw_data)
        else:
            image_list = raw_data
        for image in image_list:
            print(f"{p_id}/{t_id}/rawData/{image}")
            exist = self.trina_bucket.object_exists(f"{p_id}/{t_id}/rawData/{image}")
            if exist:
                try:
                    print(local_path)
                    self.trina_bucket.get_object_to_file(f"{p_id}/{t_id}/rawData/{image}", f"{local_path}/{image}")
                except Exception as e:
                    print(e)
                    print('download filed')
            else:
                print('file not in trina_oss')
        return image_list

    def upload_image(self, image_list, local_path):
        """
        需要先上传图片,防止任务创建之后,导致图片还没有上传成功
        :return:
        """
        for image in image_list:
            oss_path = OSS_PATH + f"{project_id}/{self.task_id}/rawData/{image}"
            print(oss_path)
            local_image_path = local_path + f"/{image}"
            print(local_image_path)
            try:
                self.cloud_bucket.put_object_with_url_from_file(oss_path, local_image_path)
            except Exception as e:
                print(e)
                logger.error(e)
        update_url = update_status_url + f"{self.task_id}/"
        requests.put(update_url, headers={'Authorization': f"Token {self.token}"}, json={'task_status': '3'})

    def login_cloud(self, phone_num, password, login_cloud_url):
        content = requests.post(login_cloud_url, json={'phone_num': phone_num, 'password': password}).json()
        print(content)
        if content.get("code") == 200:
            self.token = content['data']['token']
            self.user_id = content['data']['user_id']
            self.company_id = content['data']['company_id']
            self.application_id = content['data']['applications'][-1]
        else:
            print('登入失败')
            logger.info('登入失败')

    def create_local_path(self, t_id, p_id):
        """
        create mkdir in local
        :param t_id:
        :param p_id:
        :return:
        """

        if os.path.exists(f"{base_dir}/{p_id}/{t_id}"):
            path_list = os.listdir(f"{base_dir}/{p_id}/{t_id}")
            for path in path_list:
                try:
                    os.remove(f"{base_dir}/{p_id}/{t_id}/{path}")
                except Exception as e:
                    print(e)
                    logger.error(e)
            return f"{base_dir}/{p_id}/{t_id}"
        if not os.path.exists(f"{base_dir}/{p_id}"):
            os.mkdir(f"{base_dir}/{p_id}")
        os.mkdir(f"{base_dir}/{p_id}/{t_id}")
        return f"{base_dir}/{p_id}/{t_id}"

    def parse_content_raw_data(self, raw_data):
        """
        :param raw_data:
        :return:
        """
        raw_data_dict = json.loads(raw_data)
        image_list = [j.split('/')[-1] for j in raw_data_dict]
        return image_list

    def parse_new_raw_data(self, raw_data):
        """
        解析并且同一格式
        :param raw_data:
        :return:
        """
        data = []
        if self.survey_type == "broof" and self.is_auto_upload == "NO":
            raw_data = json.loads(raw_data)
            for i in raw_data['list']:
                for key, value in i.items():
                    if key == "name":
                        data.append(i['name'])
            return data
        return raw_data

    def run(self):
        """
        图片下载完之后需要上传图片
        :return:
        """
        while True:
            t_id, p_id, raw_data = self.trina_get_task()
            if self.t_id == t_id:
                print('timeout 10s')
                logger.info('timeout 10s')
                time.sleep(10)
                continue
            self.t_id = t_id
            if not t_id or not p_id or not raw_data:
                print('No Task To Script')
                logger.info('No Task To Script')
                time.sleep(10)
                continue
            raw_data = self.parse_new_raw_data(raw_data)
            local_path = self.create_local_path(t_id, p_id)
            image_list = self.download_image(p_id, t_id, raw_data, local_path)
            result = self.cloud_create_task()
            if not result:
                logger.info('Create Task Failed')
                continue
            self.upload_image(image_list, local_path)
            time.sleep(10)


if __name__ == '__main__':
    server = Server(trina_bucket, cloud_bucket).run()
